//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////测试非阻塞状态下的父子进程////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

using namespace std;

#define NUM 10
typedef void(*func_t)();

func_t handlerTask[NUM];

void task1()
{
    cout << "handler test1" << endl;
}

void task2()
{

    cout << "handler test2" << endl;
}

void task3()
{

    cout << "handler test3" << endl;
}

void loadTask()
{
    memset(handlerTask,0,sizeof(handlerTask));
    handlerTask[0] = task1;
    handlerTask[1] = task2;
    handlerTask[2] = task3;
}

int main()
{
    pid_t id = fork();
    assert(id != -1);
    if(id == 0){
        int cnt = 10;
        while(cnt--){
            cout << "I am child pid:" << getpid() << " "<< "ppid:" << getppid() << " " << cnt << endl;
            sleep(1);
        }
        _exit(11);
    }
    loadTask();
    int status = 0;
    while(1){
        pid_t myid = waitpid(id,&status,WNOHANG);//WHOHANG表示的是非阻塞状态->子进程没有exit，父进程检测的时候，就返回
        //测试的是调用错误情况
        //pid_t myid = waitpid(id+1,&status,WNOHANG);//WHOHANG表示的是非阻塞状态->子进程没有exit，父进程检测的时候，就返回
        if(myid == 0){//对应的就是设则的WHOHANG的情况
            //waitpid调用成功 && 子进程没有退出
            //子进程没有退出的话，那么waitpid就没有等待失败，仅仅是检测了子进程没有退出
            cout << "wait done,but child is running.....,parent running other things" << endl;
            for(int i = 0; handlerTask[i] != nullptr; i++){
                handlerTask[i]();//回调执行，让父进程在空闲时间做的进程
            }
        }
        else if(myid > 0){
            //waitpid调用成功 && 子进程安全退出
            cout << "wait succes,sig number:" << (status&0x7F) << " " << "exit code:" << ((status>>8)&0xFF) << endl;
            break;
        }
        else{
            //waitpid调用失败了，直接退出
            cout << "waitpid call failed" << endl;
            break;
        }
        sleep(1);

    }
    return 0;
}
